﻿using Module.FlowChart.Model;
using Module.FlowChart.RunAble.Logic.Sequential;
using Module.FlowChart.View;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;


namespace Module.FlowChart.RunAble.View
{
    internal sealed class ViewManager_Sequential : ViewManager_FCBase
    {
        public override string TypeName => SequentialFCWorkPage.TypeNameS;


        public ViewManager_Sequential(ViewManagerHandles h, Document doc, SequentialFCWorkPage page, Control container)
            : base(h, doc, page, container)
        {
            Info.IsRunning = () => { return IsRunning; };
            //************************* 初始化其他参数
            DropDiffer = new Size(0, 0);
        }

        #region  -----------     Menu    ---------------------------------
        private ToolStripMenuItem Menu_Run;
        private ToolStripMenuItem Menu_Run_Next;
        private ToolStripMenuItem Menu_Run_StartRun;
        private ToolStripMenuItem Menu_Run_Stop;
        protected override void CreatMenu()
        {
            Menu_Run = new ToolStripMenuItem();
            Menu_Run_StartRun = new ToolStripMenuItem();
            Menu_Run_Stop = new ToolStripMenuItem();
            Menu_Run_Next = new ToolStripMenuItem();
            // 
            // Menu_Run
            // 
            this.Menu_Run.DropDownItems.AddRange(new ToolStripItem[] {
            this.Menu_Run_StartRun,
              this.Menu_Run_Next,
            this.Menu_Run_Stop,

            });
            this.Menu_Run.Name = "Menu_Run";
            this.Menu_Run.Size = new Size(62, 28);
            this.Menu_Run.Text = "运行";
            // 
            // Menu_Run_Next
            // 
            this.Menu_Run_Next.Name = "Menu_Run_Next";
            this.Menu_Run_Next.Size = new Size(236, 34);
            this.Menu_Run_Next.Text = "下一步";
            // 
            // Menu_Run_StartRun
            // 
            this.Menu_Run_StartRun.Name = "Menu_Run_StartRun";
            this.Menu_Run_StartRun.Size = new Size(236, 34);
            this.Menu_Run_StartRun.Text = "开始单步执行";
            // 
            // Menu_Run_Stop
            // 
            this.Menu_Run_Stop.Name = "Menu_Run_Stop";
            this.Menu_Run_Stop.Size = new System.Drawing.Size(236, 34);
            this.Menu_Run_Stop.Text = "结束";

            Handles.AddMenu(Menu_Run);
            Menu_Run_StartRun.Click += (s, e) =>
            {
                runner.StartSync(SyncHandles);
                IsRunning = true;
                Menu_Run_StartRun.Enabled = false;
                Menu_Run_Next.Enabled = Menu_Run_Stop.Enabled = true;

            };
            Menu_Run_Stop.Click += (s, e) =>
            {
                Menu_Run_StartRun.Enabled = true;
                Menu_Run_Next.Enabled = Menu_Run_Stop.Enabled = false;
                IsRunning = false;
                runner.StopSync();
            };
            Menu_Run_Next.Click += (s, e) =>
            {
                if (!runner.NextSync())
                {//end
                    Menu_Run_StartRun.Enabled = true; IsRunning = false;
                    Menu_Run_Next.Enabled = Menu_Run_Stop.Enabled = false;
                }
            };


            Menu_NodeRightClick = new ContextMenuStrip();
            var m1 = new ToolStripMenuItem("删除");
            m1.Name = "Menu_NodeRightClick_Delete";
            m1.Font = new Font("宋体", 10);
            m1.Click += (s, e) =>
            {
                string msg = Info.Page.RemoveNode(Info.RightClickNode);
                if (msg != "")
                    MessageBox.Show(msg, "错误");
                else
                    SetNeedRedraw();
            };
            Menu_NodeRightClick.Items.Add(m1);
            var m2 = new ToolStripMenuItem("删除线段");
            m2.Name = "Menu_NodeRightClick_DeleteLines";
            m2.Font = new Font("宋体", 10);
            m2.Click += (s, e) =>
            {
                string msg = Info.Page.RemoveLineOfNode(Info.RightClickNode);
                if (msg != "")
                    MessageBox.Show(msg, "错误");
                else
                    SetNeedRedraw();
            };
            Menu_NodeRightClick.Items.Add(m2);
            Menu_NodeRightClick.Parent = null;

        }
        protected override void InitMenuState(bool visible)
        {
            if (visible)
            {
                Menu_Run.Visible = true;
                Menu_Run_StartRun.Enabled = true;
                Menu_Run_Stop.Enabled = false;
                Menu_Run_Next.Enabled = false;
            }
            else
            {
                Menu_Run.Visible = false;
            }

        }
        #endregion


        #region  -----------     ControllerEvent    ---------------------------------
        protected override ListViewGroup[] CreatCandidateListGroups()
        {

            string[] itemname = "矩形;菱形;圆形".Split(';');

            ListViewGroup group = new ListViewGroup("基础图形");
            ListViewItem[] items = new ListViewItem[itemname.Length];
            for (int i = 0; i < items.Length; i++)
            {
                ListViewItem lvi = new ListViewItem();

                //lvi.ImageIndex =0;     //通过与imageList绑定，显示imageList中第i项图标
                lvi.Text = itemname[i];
                items[i] = lvi;
                lvi.Group = group;
            }
            return new ListViewGroup[] { group };

        }
        protected override void OnDragFromListView(ListViewItem item)
        {
            Info.DragType = FCNodeType.Label;
            switch (item.Index)
            {
                case 0: Info.DragShape = Shape.Rect; break;
                case 1: Info.DragShape = Shape.Diamond; break;
                case 2: Info.DragShape = Shape.Circular; break;
                default: break;
            }
        }
        protected override void OnMouseUp_Running(object sender, MouseEventArgs e)
        {
            //鼠标离开
            if (e.X < 0 || e.X > Container.Width || e.Y < 0 || e.Y > Container.Height)
                return;

            if (!runner.NextSync())
            {//end
                Menu_Run_StartRun.Enabled = true;
                Menu_Run_Next.Enabled = Menu_Run_Stop.Enabled = false;
            }
        }
        #endregion

        #region  -----------     Runner    ---------------------------------
        static bool IsRunning;
        FCRunner runner;
        RunnerHandles SyncHandles;
        protected override void InitRunner()
        {
            RunnerHandles h = new RunnerHandles();

            h.CMD = (cmd) => { };
            h.SetAllNodeVisible = (b) =>
            {
                SequentialFCWorkPage p = Page as SequentialFCWorkPage;
                foreach (var nd in p.Nodes.Values)
                {
                    nd.Visible = b;
                }
                foreach (var ln in p.Lines.Values)
                {
                    ln.Visible = b;
                }
                SetNeedRedraw(true);
            };
            h.SetNodeVisible = (index, b) =>
            {
                if (b == false)
                {
                    throw new Exception("todo");
                }
                SequentialFCWorkPage p = Page as SequentialFCWorkPage;
                p.FindNode(index).Visible = b;
                foreach (var ln in p.Lines.Values)
                {
                    if (ln.Visible == false && ln.To == index && (p.FindNode(ln.From).Visible == true))
                    {
                        ln.Visible = true;
                    }
                }
                SetNeedRedraw(true);
            };
            h.GetSelectedNode = () => { return -1; };
            h.GetStartNode = () => { return Info.Page.StartNode; };
            h.GetNodeNear_NotVisible = (int id) =>
            {
                List<int> re = new List<int>();
                if (!Info.Page.Nodes.ContainsKey(id))
                    throw new Exception("NoThisNode");
                foreach (var line in Info.Page.Lines.Values)
                {
                    if (line.From == id && Info.Page.Nodes.ContainsKey(line.To) && !Info.Page.Nodes[line.To].Visible && !re.Contains(line.To))
                    {
                        re.Add(line.To);
                    }
                }
                return re;
            };
            SyncHandles = h;
            runner = new FCRunner(); ;
        }
        #endregion

        protected override PageDrawer CreatPageDrawer()
        {
            return new PageDrawer_Sequential(Info);
        }

    }
}